package com.fly.core.aspect;

import java.util.Date;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.fly.core.entity.JsonResult;
import com.fly.core.utils.HttpRequestUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * aop处理鉴权
 * 
 * @author 00fly
 * @version [版本号, 2022年11月29日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Slf4j
@Aspect
@Component
public class AuthAspect
{
    private String token = null;
    
    /**
     * token有效时间(60分钟)
     */
    private Date tokenTime;
    
    @Value("${white.list:127.0.0.1}")
    private String whiteList;
    
    /**
     * 切入点com.fly.git.web包及子包和使用PostMapping注解标注的类
     */
    @Pointcut("within(com.fly.git.web..*) && @annotation(org.springframework.web.bind.annotation.PostMapping)")
    public void point()
    {
    }
    
    @Around("point()")
    public Object around(ProceedingJoinPoint joinPoint)
        throws Throwable
    {
        HttpServletRequest request = HttpRequestUtils.getHttpServletRequest();
        if (request != null)
        {
            String ip = request.getRemoteAddr();
            String token = request.getHeader("token");
            log.info("★★★★★★★★ request ip: {}, head token : {}", ip, token);
            if (!StringUtils.contains(whiteList, ip) && !StringUtils.equals(token, getToken()))
            {
                return JsonResult.error("禁止访问，请添加白名单IP：" + ip + "或设置合法token");
            }
        }
        return joinPoint.proceed();
    }
    
    /**
     * 获取token
     * 
     * @return
     * @see [类、类#方法、类#成员]
     */
    private synchronized String getToken()
    {
        Date now = new Date();
        if (tokenTime == null || now.after(tokenTime))
        {
            token = UUID.randomUUID().toString().replace("-", "");
            tokenTime = DateUtils.addMinutes(now, 60);
        }
        log.info("------ now valid token is： {}", token);
        return token;
    }
}